package be.android.forap.gui;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import be.android.forap.Constants;
import be.android.forap.crypto.CryptoUtil;
import be.android.forap.dataprovider.ContactManager;
import be.android.forap.dataprovider.ContactUtil;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

public class DownloadActivity extends Activity {


	public static final String SENDER_DL_LINK = "SENDER_DL_LINK";
	public static final String DOWNLOAD_PATH = "DOWNLOAD_PATH";
	public static final String DOWNLOAD_CONTENT = "DOWNLOAD_CONTENT";
	public static final String DOWNLOAD_SIZE = "DOWNLOAD_SIZE";
	public static final String DOWNLOAD_DIGEST = "DOWNLOAD_DIGEST";

	// declare the dialog as a member field of your activity
	ProgressDialog mProgressDialog;
	int mFileSize;
	String digest;
	String number;

	boolean isEncryptedMessage=false;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setResult(RESULT_CANCELED, getIntent());
		Intent launcher = getIntent();
		String url = launcher.getStringExtra(DOWNLOAD_PATH);
		String size = launcher.getStringExtra(DOWNLOAD_SIZE);
		digest = launcher.getStringExtra(DOWNLOAD_DIGEST);

		if(TextUtils.isEmpty(digest))
			isEncryptedMessage = true;

		number = launcher.getStringExtra(SENDER_DL_LINK);
		Log.d("n",number);
		Log.i("DL","size "+size);
		mFileSize = Integer.parseInt(size);


		// instantiate it within the onCreate method
		mProgressDialog = new ProgressDialog(DownloadActivity.this);
		mProgressDialog.setMessage("Downloading...");
		mProgressDialog.setIndeterminate(false);
		mProgressDialog.setMax(100);
		mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

		// execute this when the downloader must be fired
		DownloadFile downloadFile = new DownloadFile();
		downloadFile.execute(url);
	}

	private void processDownloadedMessage(String content) {
		/*getIntent().putExtra(DOWNLOAD_CONTENT, content);
		setResult(RESULT_OK, getIntent());*/
		try {
			String state = Environment.getExternalStorageState();
			if (Environment.MEDIA_MOUNTED.equals(state)) {
				File sdCard = Environment.getExternalStorageDirectory();
				final File dir = new File (sdCard.getAbsolutePath() + "/ForAp/sms");
				if(!dir.exists())
					dir.mkdirs();
				File file = new File(dir, "sms.txt.enc");
				FileOutputStream f = new FileOutputStream(file,false);
				f.write(content.getBytes());
				f.close();
				Intent decryptIntent = new Intent(this, MainActivity.class);
				decryptIntent.setAction(Constants.DECRYPT_SMS_FILE_ACTION);
				Log.d("DL",number+"wtf"+file.getAbsolutePath());
				decryptIntent.putExtra(MainActivity.SMS_NUMBER, number);
				decryptIntent.putExtra(MainActivity.CONTENT_SMS, file.getAbsolutePath());
				startActivity(decryptIntent);
			}else{
				Toast.makeText(getApplicationContext(), "Error, no (writable) sdcard is mounted!", Toast.LENGTH_SHORT).show();
			}
			
			//editIntent.putExtra(ContactAdder.CONTACT_LNAME, contact.getLastName());
			//decryptIntent.putExtra(ContactAdder.CONTACT_PHONE, number);
			//decryptIntent.putExtra(ContactAdder.CONTACT_PUBKEY, content);
			//startActivity(decryptIntent);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finish();				
	}

	private void processDownloadedKey(String content) {
		/*getIntent().putExtra(DOWNLOAD_CONTENT, content);
		setResult(RESULT_OK, getIntent());*/
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("SHA-256");
			md.update(content.getBytes()); // Change this to "UTF-16" if needed
			byte[] contentDigest = md.digest();
			if(CryptoUtil.toHexNoSpaces(contentDigest).equals(digest)){
				Intent editIntent = new Intent(this, ContactAdder.class);

				String name = ContactUtil.getContactName(getApplicationContext(), number);
				editIntent.putExtra(ContactAdder.CONTACT_FNAME, name);
				//editIntent.putExtra(ContactAdder.CONTACT_LNAME, contact.getLastName());
				editIntent.putExtra(ContactAdder.CONTACT_PHONE, number);
				editIntent.putExtra(ContactAdder.CONTACT_PUBKEY, content);
				startActivity(editIntent);
			}else{
				Toast.makeText(getApplicationContext(), "Integrity check of public key failed", Toast.LENGTH_LONG).show();
			}			
		} catch (NoSuchAlgorithmException e) {
			Toast.makeText(getApplicationContext(), "Error processing downloaded content", Toast.LENGTH_LONG).show();
		}
		finish();				
	}

	// usually, subclasses of AsyncTask are declared inside the activity class.
	// that way, you can easily modify the UI thread from here
	private class DownloadFile extends AsyncTask<String, Integer, String> {
		@Override
		protected String doInBackground(String... sUrl) {
			String ret = null;
			try {
				URL url = new URL(sUrl[0]);
				/*URLConnection connectionTemp = url.openConnection();
				Log.e("DL",""+connectionTemp.toString());
				connectionTemp.connect();
				Log.e("DL",""+connectionTemp.toString());
				// this will be useful so that you can show a typical 0-100% progress bar
				int fileLength = connectionTemp.getContentLength();
				Log.e("DL",""+connectionTemp.toString());




				String downloadUrl = connectionTemp.getURL().toString();
				downloadUrl = downloadUrl + "?dl=1";*/
				HttpURLConnection.setFollowRedirects(true);
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				connection.connect();
				connection.getResponseMessage();
				String redirectionLink = connection.getURL().toString();

				String downloadLink = redirectionLink + "?dl=1";
				URL downloadUrl = new URL(downloadLink);
				URLConnection dlConnection = downloadUrl.openConnection();
				dlConnection.connect();



				// download the file
				InputStream input = new BufferedInputStream(downloadUrl.openStream());
				//OutputStream output = new FileOutputStream("/sdcard/file_name.extension");

				// this will be useful so that you can show a typical 0-100% progress bar
				int fileLength = mFileSize;//51;//filesize//connection.getContentLength();
				Log.e("DL","  "+fileLength);

				ByteArrayOutputStream output = new ByteArrayOutputStream();

				byte data[] = new byte[1024];
				long total = 0;
				int count;
				while ((count = input.read(data)) != -1) {
					total += count;
					// publishing the progress....
					publishProgress((int) (total * 100 / fileLength));
					output.write(data, 0, count);
				}

				output.flush();
				ret = new String(output.toByteArray());
				output.close();
				input.close();
			} catch (Exception e) {
				Log.e("DL",e.toString());
			}
			return ret;
		}

		private int tryGetFileSize(URL url) {
			HttpURLConnection conn = null;
			try {
				conn = (HttpURLConnection) url.openConnection();
				conn.setRequestMethod("HEAD");
				conn.getInputStream();
				return conn.getContentLength();
			} catch (IOException e) {
				return -1;
			} finally {
				conn.disconnect();
			}
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mProgressDialog.show();
		}

		@Override
		protected void onProgressUpdate(Integer... progress) {
			super.onProgressUpdate(progress);
			mProgressDialog.setProgress(progress[0]);
		}

		@Override
		protected void onPostExecute(String result){
			mProgressDialog.dismiss();
			if(isEncryptedMessage){
				processDownloadedMessage(result);
			}else{
				processDownloadedKey(result);				
			}
		}
	}
}
